package com.leyou.item.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.leyou.common.pojo.PageResult;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.mapper.StockMapper;
import com.leyou.item.service.BrandService;
import com.leyou.item.service.CategoryService;
import com.leyou.item.service.GoodsService;
import com.leyou.pojo.*;
import com.leyou.bo.SpuBo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @author XiaoLuo
 * @ClassName: GoodsServiceImpl
 * @Description: ${todo}
 * @date 2019/4/18 15:40
 */
@Service public class GoodsServiceImpl implements GoodsService {

	@Autowired private SkuMapper skuMapper;
	@Autowired private SpuDetailMapper spuDetailMapper;
	@Autowired private SpuMapper spuMapper;
	@Autowired private CategoryService categoryService;
	@Autowired private BrandService brandService;
	@Autowired private StockMapper stockMapper;

	/**
	 * 根据页面传入的查询条件分页查询spu商品列表
	 *
	 * @param key
	 * @param saleable
	 * @param page
	 * @param rows
	 * @return
	 */
	@Override public PageResult<SpuBo> querySpuByPage(String key,
			Boolean saleable, Integer page, Integer rows) {
		//开始分页
		PageHelper.startPage(page, rows);
		// 创建查询条件
		Example example = new Example(Spu.class);
		Example.Criteria criteria = example.createCriteria();

		//是否过滤上下架
		if (saleable != null) {
			criteria.orEqualTo("saleable", saleable);
		}
		//动态sql查询 key是否为空
		//不为空根据key查询
		if (StringUtils.isNotBlank(key)) {
			criteria.andLike("title", "%" + key + "%");
		}

		Page<Spu> spuPage = (Page<Spu>) this.spuMapper.selectByExample(example);

		//用来存放spuBo
		List<SpuBo> spuBos = new ArrayList<>();
		//获取查询到的结果中所有的spu
		List<Spu> spus = spuPage.getResult();

		spus.forEach(spu -> {

			SpuBo spuBo = new SpuBo();
			//对应属性拷贝
			BeanUtils.copyProperties(spu, spuBo);

			//拿到了分类的id，但是呢缺分类的名称，所以需要根据id查询名称
			// 2、查询spu的商品分类名称,要查三级分类
			List<String> names = this.categoryService.queryNamesByIds(
					Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));

			// //把查询到的分类的集合名称通过join转为字符串，赋值给cname
			spuBo.setCname(StringUtils.join(names, "/"));
			//根据品牌的id查询品牌对象，并获取名称
			Brand brand = this.brandService.queryBrandById(spu.getBrandId());
			spuBo.setBname(brand.getName());
			spuBos.add(spuBo);

		});

		return new PageResult<>(spuPage.getTotal(),
				new Long(spuPage.getPages()), spuBos);
	}

	/**
	 * 新增商品
	 *
	 * @param spuBo
	 */
	@Override @Transactional public void save(SpuBo spuBo) {
		//保存spu
		spuBo.setSaleable(true);
		spuBo.setValid(true);
		spuBo.setCreateTime(new Date());
		spuBo.setLastUpdateTime(spuBo.getCreateTime());
		this.spuMapper.insert(spuBo);
		//保存spuDetail详情 回显ID
		SpuDetail spuDetail = spuBo.getSpuDetail();
		spuDetail.setSpuId(spuBo.getId());
		this.spuDetailMapper.insert(spuDetail);

		//保存sku和库存信息
		saveSkuAndStock(spuBo.getSkus(), spuBo.getId());
		/*List<Sku> skus= spuBo.getSkus();
		//迭代集合保存
		skus.forEach(sku -> {
			sku.setSpuId(spuBo.getId());
			//初始化时间
			sku.setCreateTime(new Date());
			sku.setLastUpdateTime(sku.getCreateTime());
			//保存skub并回显ID
			this.skuMapper.insert(sku);
			//保存库存信息
			Stock stock = new Stock();
			stock.setSkuId(sku.getId());
			stock.setStock(sku.getStock());
			this.stockMapper.insert(stock);
		});*/
		System.out.println("spuBo = " + spuBo);
	}

	/**
	 * 修改商品栏时
	 * 根据spuid回显商品的spudetail属性
	 *
	 * @param spuId
	 * @return
	 */
	@Override public SpuDetail querySpuDetailById(Long spuId) {
		return this.spuDetailMapper.selectByPrimaryKey(spuId);

	}

	/**
	 * 修改商品烂时
	 * 根据supid回显商品sku属性
	 *
	 * @param spuId
	 * @return
	 */
	@Override public List<Sku> querySkuBySpuId(Long spuId) {
		//由于spu的ID不是sku的主键 所以做属性查询
		Sku sku = new Sku();
		sku.setSpuId(spuId);
		//根据spuid查询出所有的sku
		List<Sku> skus = this.skuMapper.select(sku);
		//根据sku的ID查询库存stock
		skus.forEach(sku1 ->
				//sku的id就是stock的主键(sku实体类有stock)
				sku1.setStock(this.stockMapper.selectByPrimaryKey(sku1.getId())
						.getStock()));
		return skus;
	}

	/**
	 * 保存修改的商品信息
	 *
	 * @param spuBo
	 */
	@Override
	@Transactional
	public void update(SpuBo spuBo) {
		//最后提交的时间要改
		spuBo.setLastUpdateTime(new Date());
		this.spuMapper.updateByPrimaryKeySelective(spuBo);
		//修改的话  先删除之前的sku 在添加进去
		//所以先查到 然后在删除
		Sku sku = new Sku();
		sku.setSpuId(spuBo.getId());
		List<Sku> list = this.skuMapper.select(sku);
		list.forEach(skus -> this.skuMapper.delete(skus));
		//细节 这里最好设置null  可以节省资源，提前进入垃圾回收
		list=null;
		//最后开始循环添加
		saveSkuAndStock(spuBo.getSkus(),spuBo.getId());
		//这里为了debug而用
		System.out.println("spuBo = " + spuBo);
	}

	private void saveSkuAndStock(List<Sku> skus, Long spuId) {
		skus.forEach(sku -> {
			//保存sku
			sku.setSpuId(spuId);
			//初始化时间
			sku.setCreateTime(new Date());
			sku.setLastUpdateTime(sku.getCreateTime());
			this.skuMapper.insert(sku);
			//保存库存信息
			Stock stock = new Stock();
			stock.setSkuId(sku.getId());
			stock.setStock(sku.getStock());
			this.stockMapper.insert(stock);
		});
	}
}
